/*
 *  Copyright 2010-2011 Mark Eschbach
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 * $HeadURL: https://meschbach.com/svn/software/mee-utils/trunk/psi-jetty/src/main/java/com/meschbach/psi/jetty/LocalJettyBuilder.java $
 * $Id: LocalJettyBuilder.java 2839 2011-01-27 23:31:54Z meschbach $
 */
package com.meschbach.psi.jetty;

import com.meschbach.psi.Container;
import com.meschbach.psi.ContainerFactory;
import com.meschbach.psi.PSIException;

/**
 * A <code>LocalJettyBuilder</code> is a factory for the construction of an
 * in-process Jetty service.  By default a <code>LocalJettyBuilder</code> will
 * construct the service on operating system port, however if you choose you may
 * lock down the service to a specific port.
 *
 * This class is copyright 2010-2011 by Mark Eschbach and is licensed under the
 * Apache License, Version 2.0; accessible at
 * http://www.apache.org/licenses/LICENSE-2.0.<p>
 * 
 * @author "Mark Eschbach" &lt;meschbach@gmail.com&gt;
 * @version 1.0.4
 * @since 2.0.0
 */
public class LocalJettyBuilder implements ContainerFactory {

    /**
     * The <code>port</code> is the port to attempt to bind too.
     */
    protected int port;

    /**
     * Constructs a new <code>LocalJettyBuilder</code> setup to allow the
     * operating system to choose the port.
     *
     * #see #setPort(int)
     */
    public LocalJettyBuilder() {
        port = 0;
    }

    /**
     * Retrieves the port to attempt to bind the instance of Jetty too.  If the
     * port is zero, then the operating system will choose the port.
     * 
     * @return the por to attempt to bind too
     */
    public int getPort() {
        return port;
    }

    /**
     * Sets the port to attempt to bind too.  If the <code>port</code> is zero
     * then the operating system will choose the port.
     * 
     * @param port the port to construct our instance
     * @return this object
     */
    public LocalJettyBuilder setPort(int port) {
        this.port = port;
        return this;
    }

    /**
     * Constructs a new instance of Jetty in process with an instance of
     * the PSI interface <code>Client</code> returned for the control of the
     * Jetty service.
     *
     * @return an instance of Client for contorlling the Jetty process.
     * @throws PSIException
     */
    public JettyContextManagerClient build() throws PSIException {
        JettyWebContainer jwc = new JettyWebContainer();
        int realPort = jwc.start(port);
        String server = "http://localhost:" + realPort;
        String context = server + "/psi";
        return new JettyContextManagerClient(server, context);
    }

    /**
     * Constructs a new instance with the build()V method on this object.
     * @return a new container
     * @throws PSIException if any problems occur while constructing the container
     * @see LocalJettyBuilder#build() 
     */
    public Container buildContainer() throws PSIException {
        return build();
    }

    /**
     * Constructs a new Jetty instance on an operating system selected port.
     * This method is a utility to make instatiation easier.
     * 
     * @return a new instance of a Client to control the context.
     * @throws PSIException if a problem occurs.
     */
    public static JettyContextManagerClient buildService() throws PSIException {
        return new LocalJettyBuilder().build();
    }
}
